package com.hippo.core.core.network.response

import androidx.annotation.Keep
import com.hippo.core.config.AppConsts
import com.hippo.core.event.MessageEvent
import com.hippo.core.event.MessageEventBus
import com.hippo.core.utils.UiHandler
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flowOf
import kotlinx.serialization.Serializable

@Keep
@Serializable
data class ApiResponse<T>(
    val retCode: Int? = null,
    val retMsg: String? = null,
    val retData: T? = null
){


    companion object {

        const val SUCCESS_CODE = 200

        fun <T> success(data: T? = null): ApiResponse<T> {
            return ApiResponse(SUCCESS_CODE, "success", data)
        }

        fun <T> failure(msg: String? = null): ApiResponse<T> {
            return ApiResponse(400, msg)
        }

    }


    fun isSuccess(): Boolean {
        return retCode == SUCCESS_CODE
    }



    suspend fun then(block:suspend (T?) -> Unit) = apply {
        if(isSuccess()){
            block(this.retData)
        }
    }

    fun onSuccess(action: (T?) -> Unit) = apply {
        if (isSuccess() ) {
            action(retData)
        }else{
            if(retCode == AppConsts.HttpCode.LOGIN_INVALID){
                MessageEventBus.post(MessageEvent.TokenExpired)
            }
        }
    }

    suspend fun handleFailure(block: (() -> Unit)? = null) = apply {
        if (!isSuccess()) {
            onFailure{
                block?.invoke()
            }
            UiHandler.showToast(retMsg?:"网络异常")
        }
        block?.invoke()
    }

    fun asFlow(): Flow<T?> {
        return flowOf(retData)
    }


    /**
     * 校验请求是否失败或者数据为空，用于需要返回数据的接口
     */
     fun onFailure(action: (ErrorCode) -> Unit) = apply {
        if (!isSuccess()) {
            action(ErrorCode(code = retCode?:400,msg = retMsg))
        }
    }


}

